package com.filetransfer.common;

import lombok.Data;

import java.nio.ByteBuffer;

/**
 * 自定义协议数据包结构
 */
@Data
public class Packet {
    // 协议常量
    public static final int MAGIC = 0xDEADBEEF;
    
    // 包类型
    public static final int TYPE_REQUEST_FILE = 1;      // 请求文件
    public static final int TYPE_FILE_DATA = 2;         // 文件数据
    public static final int TYPE_ACK = 3;               // 确认
    public static final int TYPE_FINISH = 4;            // 结束
    public static final int TYPE_NACK = 5;              // 否定确认
    
    // 包结构字段
    private int magic;      // 魔数，固定值0xDEADBEEF
    private int type;       // 包类型
    private int seqId;      // 序列号
    private int length;     // Body长度
    private byte[] body;    // 数据内容
    
    // 标志位（用于扩展功能）
    private boolean compressed;    // 是否压缩
    private boolean encrypted;     // 是否加密
    
    public Packet() {
        this.magic = MAGIC;
    }
    
    public Packet(int type, int seqId, byte[] body) {
        this.magic = MAGIC;
        this.type = type;
        this.seqId = seqId;
        this.body = body;
        this.length = (body != null) ? body.length : 0;
    }
    
    /**
     * 将数据包序列化为字节数组
     */
    public byte[] toBytes() {
        // 头部16字节 + 数据长度
        ByteBuffer buffer = ByteBuffer.allocate(16 + length);
        buffer.putInt(magic);
        buffer.putInt(type);
        buffer.putInt(seqId);
        buffer.putInt(length);
        if (body != null && length > 0) {
            buffer.put(body);
        }
        return buffer.array();
    }
    
    /**
     * 从字节数组反序列化数据包
     */
    public static Packet fromBytes(byte[] data) {
        if (data == null || data.length < 16) {
            throw new IllegalArgumentException("数据包长度不足");
        }
        
        ByteBuffer buffer = ByteBuffer.wrap(data);
        Packet packet = new Packet();
        packet.magic = buffer.getInt();
        packet.type = buffer.getInt();
        packet.seqId = buffer.getInt();
        packet.length = buffer.getInt();
        
        if (packet.length > 0 && buffer.remaining() >= packet.length) {
            packet.body = new byte[packet.length];
            buffer.get(packet.body);
        }
        
        // 验证魔数
        if (packet.magic != MAGIC) {
            throw new IllegalArgumentException("无效的数据包魔数");
        }
        
        return packet;
    }
}